package rest

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

const code = "code" // 這是內部的code, 不是http status code
const msg = "msg"
const data = "data"

/*
ResponseWrapper 统一的响应结果
*/
type ResponseWrapper struct {
	httpStatusCode int
	h              gin.H
}

/*
WithCode 设置Code
*/
func (t *ResponseWrapper) WithCode(c int) *ResponseWrapper {
	return t.With(code, c)
}

/*
WithHttpCode 设置http status code
*/
func (t *ResponseWrapper) WithHttpCode(statusCode int) *ResponseWrapper {
	t.httpStatusCode = statusCode
	return t
}

/*
WithMsg 设置提示消息
*/
func (t *ResponseWrapper) WithMsg(m string) *ResponseWrapper {
	return t.With(msg, m)
}

/*
WithData 设置数据
*/
func (t *ResponseWrapper) WithData(d any) *ResponseWrapper {
	return t.With(data, d)
}

/*
Send 发送结果
*/
func (t *ResponseWrapper) Send(c *gin.Context) {
	if t.httpStatusCode == 0 { // 默认200
		t.httpStatusCode = http.StatusOK
	}

	c.JSON(t.httpStatusCode, t.h)
}

/*
Success 成功，使用...来模拟可选参数
*/
func Success(d ...any) *ResponseWrapper {
	wrapper := ResponseWrapper{
		h: gin.H{
			code: http.StatusOK, // 這個是body, 不是http狀態碼
			msg:  "操作成功",
			data: nil,
		},
	}
	if len(d) > 0 && d[0] != nil {
		wrapper.h[data] = d[0]
	}
	return &wrapper
}

/*
Fail 失败，使用...来模拟可选参数
*/
func Fail(errs ...error) *ResponseWrapper {
	wrapper := ResponseWrapper{
		h: gin.H{
			code: http.StatusInternalServerError,
			data: nil,
		},
	}
	if len(errs) > 0 && errs[0] != nil {
		wrapper.h[msg] = errs[0].Error()
	}
	return &wrapper
}

/*
FailWithCode 失败同时附加状态码
*/
func FailWithCode(m string, c int) *ResponseWrapper {
	wrapper := &ResponseWrapper{
		h: gin.H{
			code: c, // 這個是response body, 不是http status
			msg:  m,
			data: nil,
		},
	}
	return wrapper
}

// With 继续附加数据
// 如果k的值是slice，那么这个标签会重复（xml下）
func (t *ResponseWrapper) With(k string, v any) *ResponseWrapper {
	t.h[k] = v
	return t
}

func (t *ResponseWrapper) WithMap(m map[string]any) *ResponseWrapper {
	for k, v := range m {
		t.h[k] = v
	}
	return t
}
